package com.dongdongshop.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dongdongshop.mapper.TbSeckillGoodsMapper;
import com.dongdongshop.mapper.TbSeckillOrderMapper;
import com.dongdongshop.pojo.TbSeckillGoods;
import com.dongdongshop.pojo.TbSeckillGoodsExample;
import com.dongdongshop.pojo.TbSeckillOrder;
import com.dongdongshop.service.SeckillService;
import com.dongdongshop.util.IdWorker;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@DubboService
public class SeckillServiceImpl implements SeckillService {
    @Autowired
    private TbSeckillGoodsMapper tbSeckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public List<TbSeckillGoods> findSeckillList() {
        //给redis的value值序列化
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        //整合redis缓存
        List<TbSeckillGoods> seckillGoodsList = redisTemplate.boundHashOps("seckill_goods_list").values();//取出所有的商品数据

        if (seckillGoodsList == null || seckillGoodsList.size() <= 0){
            //秒杀商品的查询
            TbSeckillGoodsExample example = new TbSeckillGoodsExample();
            TbSeckillGoodsExample.Criteria criteria = example.createCriteria();
            criteria.andStatusEqualTo("1");//审核查询
            criteria.andStockCountGreaterThan(0);//库存还有
            Date now = new Date();
            //当前时间要是大于秒杀的开始时间
            criteria.andStartTimeLessThanOrEqualTo(now);
            //当前时间要是小于秒杀的结束时间
            criteria.andEndTimeGreaterThanOrEqualTo(now);
            seckillGoodsList = tbSeckillGoodsMapper.selectByExample(example);
            //将查询出来的商品数据，添加到redis中
            for (TbSeckillGoods goods : seckillGoodsList) {
                redisTemplate.boundHashOps("seckill_goods_list").put(goods.getId(),goods);
                //将预减库存单独拿出来放到redis中  注意事项：首先在redis中value值要使用自减命令需要先序列化成字符串
                redisTemplate.boundValueOps(goods.getId()).set(goods.getStockCount().toString());
            }
        }

        return seckillGoodsList;
    }

    @Override
    public TbSeckillGoods selectById(Long id) {
        return (TbSeckillGoods) redisTemplate.boundHashOps("seckill_goods_list").get(id);
    }

    @Override
    public void createOrder(Long id, String username) throws Exception {
        //查询商品信息
        //判断商品是否已经售罄
        String stockCount = (String)redisTemplate.boundValueOps(id).get();
        if (stockCount == null){
            throw new Exception("商品已售罄！");
        }

        //当值库存卖超/超卖
        if (Integer.valueOf(stockCount) <= 0){
            throw new Exception("商品已售罄！");
        }

        String usernameId = username + id;
        //每个用户只能秒杀一次
        redisTemplate.boundHashOps("seckill-username-goodId").put(usernameId,"1");

        //扣减库存  1.将三步变成一步  2.保证代码的原子性（加锁)
        //redis的自增或者自减
        Long decrement = redisTemplate.boundValueOps("id").decrement();
        if (decrement == 0){
            //删掉缓存，并且更新数据库
            TbSeckillGoods seckillGoods = (TbSeckillGoods) redisTemplate.boundHashOps("seckill_goods_list").get(id);
            redisTemplate.boundHashOps("seckill_goods_list").delete(id);
            seckillGoods.setStockCount(0);
            tbSeckillGoodsMapper.updateByPrimaryKey(seckillGoods);
        }
//        TbSeckillGoods seckillGoods = (TbSeckillGoods) redisTemplate.boundHashOps("seckill_goods_list").get(id);
//        if (seckillGoods == null){
//            throw new Exception("商品已售罄！");
//        }
//
//        //当值库存卖超/超卖
//        if (seckillGoods.getStockCount() <= 0){
//            throw new Exception("商品已售罄！");
//        }
//        //扣减库存  1.将三步变成一步  2.保证代码的原子性（加锁)
////        seckillGoods.setStockCount(seckillGoods.getStockCount()-1);
//        //redis的自增或者自减
//        redisTemplate.boundValueOps("").decrement();
//        //同步缓存
//        redisTemplate.boundHashOps("seckill_goods_list").put(id,seckillGoods);
//        //如果只剩最后一件，刚好卖完
//        if (seckillGoods.getStockCount() == 0){
//            //删掉缓存，并且更新数据库
//            redisTemplate.boundHashOps("seckill_goods_list").delete(id);
//            tbSeckillGoodsMapper.updateByPrimaryKey(seckillGoods);
//        }


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("goodsId",id);
        jsonObject.put("username",username);
        //JSONObject.toJSONString()默认忽略值为null的属性,SONObject.toJSONString()将实体对象转换成JSON字符串时默认是忽略值为null的属性，以及如何设置包含值为null的属性。
        rocketMQTemplate.convertAndSend("seckill-topic",jsonObject.toJSONString());

        //生成订单(改为异步mq生成）
//        Long orderId = idWorker.nextId();
//        TbSeckillOrder seckillOrder = new TbSeckillOrder();
////        seckillOrder.setTransactionId(); 交易流水号
////        seckillOrder.setReceiver(); 收货人
////        seckillOrder.setPayTime(); 支付时间
//        seckillOrder.setCreateTime(new Date());
//        seckillOrder.setMoney(seckillGoods.getCostPrice());
//        seckillOrder.setSeckillId(id);
//        seckillOrder.setStatus("0");
//        seckillOrder.setSellerId(seckillGoods.getSellerId());//商家id
//        seckillOrder.setUserId(username);
//        seckillOrder.setId(orderId);
//        //seckillOrder.setReceiverMobile();收货人手机号
//        //seckillOrder.setReceiverAddress(); 收货地址
//        tbSeckillOrderMapper.insertSelective(seckillOrder);
    }

    @Override
    public Long getOrderId(String username) {
        return (Long) redisTemplate.boundHashOps("seckill-order-id").get(username);
    }
}
